<template>
  <div class="flex justify-between mb-10px">
    <div>
      <TypographyText class="mr-10px">所属企业:</TypographyText>
      <Select
        ref="select"
        v-model:value="tenant"
        :allowClear="true"
        :field-names="{ label: 'tenantName', value: 'tenantCode' }"
        :options="tenantOptions"
        class="mr-10px"
        style="width: 240px"
      ></Select>
      <TypographyText>所属应用:</TypographyText>
      <Select
        ref="select"
        v-model:value="app"
        :allowClear="true"
        :field-names="{ label: 'appName', value: 'appId' }"
        :options="appOptions"
        class="mr-10px"
        style="width: 240px"
      ></Select>
      <Button class="mr-10px" @click="handleReset">重置</Button>
      <Button type="primary" @click="getScene">查询</Button>
    </div>
    <div>
      <Button v-per="'addBusiness'" type="primary" @click="showDrawer">新增业务场景</Button>
    </div>
  </div>
  <div>
    <div>
      <Table
        :bordered="true"
        :columns="sceneColumns"
        :dataSource="dataSource"
        :loading="loading"
        :pagination="pagination"
        :scroll="scroll"
        class="main-table"
        show-size-changer
        @change="handleTableChange"
        @resizeColumn="handleResizeColumn"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'action'">
            <span v-per="'updateBusiness'">
              <a @click="onEdit(record.id)">编辑</a>
            </span>
            <Divider type="vertical" />
            <span v-per="'businessDetail'"> <a @click="onDetails(record.id)">详细信息</a></span>
            <Divider type="vertical" />
            <span v-per="'deleteBusiness'">
              <Popconfirm cancel-text="取消" ok-text="确认" title="是否确认删除?" @confirm="onDel(record)">
                <a>删除</a>
              </Popconfirm></span
            >
          </template>
        </template>
      </Table>
    </div>
    <Drawer
      :body-style="{ paddingBottom: '80px' }"
      :closable="false"
      :footer-style="{ textAlign: 'right' }"
      :visible="detailsVisible"
      :width="700"
      title="业务详情"
      @close="detailsClose"
    >
      <Descriptions bordered>
        <DescriptionsItem :span="3" label="业务场景名称">{{ detailsDataSource.scenarioName }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="所属应用">{{ detailsDataSource.appName }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="所属企业">{{ detailsDataSource.tenantName }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="API路径">{{ detailsDataSource.apiPath }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="业务ID">{{ detailsDataSource.id }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="请求方式">{{ detailsDataSource.requestMethod }}</DescriptionsItem>
        <DescriptionsItem :span="3" label="描述">{{ detailsDataSource.description }}</DescriptionsItem>
      </Descriptions>
      <title>Header详情</title>
      <Divider title="Header详情"></Divider>
      <Table :columns="detailsHeaderColumns" :dataSource="detailsHeaderDataSource" :pagination="false"></Table>
    </Drawer>
    <Drawer
      ref="drawerRef"
      :body-style="{ paddingBottom: '80px' }"
      :closable="false"
      :footer-style="{ textAlign: 'right' }"
      :title="title"
      :visible="visible"
      :width="720"
      @close="onClose"
    >
      <Form ref="formRef" :model="form" :rules="rules" autocomplete="off" layout="vertical">
        <Row :gutter="16">
          <Col :span="12">
            <FormItem label="业务场景名称" name="scenarioName">
              <Input v-model:value="form.scenarioName" placeholder="Please enter user scenarioName" />
            </FormItem>
          </Col>
          <Col :span="12">
            <FormItem label="所属应用" name="appId">
              <Select
                v-model:value="form.appId"
                :allowClear="true"
                :field-names="{ label: 'appName', value: 'appId' }"
                :options="appOptions"
              />
            </FormItem>
          </Col>
        </Row>
        <Row :gutter="16">
          <Col :span="12">
            <FormItem label="所属企业" name="tenantCode">
              <Select
                v-model:value="form.tenantCode"
                :allowClear="true"
                :disabled="tenantSwatch"
                :field-names="{ label: 'tenantName', value: 'tenantCode' }"
                :options="tenantAddOptions"
              >
              </Select>
            </FormItem>
          </Col>
          <Col :span="12">
            <FormItem label="请求方式" name="requestMethod">
              <Select v-model:value="form.requestMethod" :allowClear="true" placeholder="Please choose the approver">
                <SelectOption value="GET">Get</SelectOption>
                <SelectOption value="POST">Post</SelectOption>
                <SelectOption value="PUT">Put</SelectOption>
                <SelectOption value="DELETE">Delete</SelectOption>
              </Select>
            </FormItem>
          </Col>
        </Row>
        <Row :gutter="16">
          <Col :span="24">
            <FormItem label="API路径" name="apiPath">
              <Input v-model:value="form.apiPath" placeholder="Please enter user apiPath" />
            </FormItem>
          </Col>
        </Row>
        <Row :gutter="16">
          <Col :span="24">
            <FormItem label="描述" name="description">
              <Textarea v-model:value="form.description" :rows="4" placeholder="please enter url description" />
            </FormItem>
          </Col>
        </Row>
      </Form>
      <Button class="editable-add-btn" style="margin-bottom: 8px" @click="handleAdd">添加header</Button>
      <Table :columns="headerColumns" :dataSource="headerDataSource" :pagination="false" bordered>
        <template #bodyCell="{ column, record, index }">
          <template v-if="column.key === 'headerKey'">
            <Input v-model:value="headerDataSource[index].headerKey" style="display: flex" />
          </template>
          <template v-if="column.key === 'headerMatch'">
            <Select v-model:value="headerDataSource[index].headerMatch" :allowClear="true" style="display: flex">
              <SelectOption value="contains">contains</SelectOption>
              <SelectOption value="exact">exact</SelectOption>
              <SelectOption value="exact">prefix</SelectOption>
            </Select>
          </template>
          <template v-if="column.key === 'headerValue'">
            <Input v-model:value="headerDataSource[index].headerValue" style="display: flex" />
          </template>
          <template v-if="column.dataIndex === 'operation'">
            <Popconfirm v-if="headerDataSource.length" title="确定要删除吗?" @confirm="onDelete(record.key)">
              <a>删除</a>
            </Popconfirm>
          </template>
        </template>
      </Table>

      <template #footer>
        <Space>
          <Button @click="onClose">取消</Button>
          <Button type="primary" @click="onSub">提交</Button>
        </Space>
      </template>
    </Drawer>
  </div>
</template>

<script lang="ts" setup>
import { computed, Ref, ref, watch } from 'vue';
import {
  Button,
  Col,
  Descriptions,
  DescriptionsItem,
  Divider,
  Drawer,
  Form,
  FormItem,
  Input,
  message,
  Popconfirm,
  Row,
  Select,
  SelectOption,
  Space,
  Table,
  TableProps,
  Textarea,
  TypographyText,
} from 'ant-design-vue';
import {
  AppItem,
  SceneDetailItem,
  SceneListItem,
  SceneParamItem,
  TenantItem,
} from '/@/api/maintenance-center/microservice-govern/scene/model/sceneModel';
import {
  createScene,
  deleteScene,
  editScene,
  getAppList,
  getSceneList,
  getTenantByAppId,
  getTenantList,
  viewScene,
} from '/@/api/maintenance-center/microservice-govern/scene/scene';
import type { Rule } from 'ant-design-vue/es/form';
import {
  detailsHeaderColumns,
  form,
  headerColumns,
  sceneColumns,
} from '/@/views/maintenance-center/microservice-govern/components/scenario';

const scroll = ref<undefined | object>(undefined);
const loading = ref(true);
// 业务场景
let tenant = ref('');
let app = ref('');
let title = ref('');
let tenantSwatch = ref(true);

const tenantOptions = ref<TenantItem[]>([]);
const tenantAddOptions = ref<TenantItem[]>([]);
const appOptions = ref<AppItem[]>([]);
let dataSource = ref<SceneListItem[]>([]);
let detailsDataSource = ref<SceneDetailItem>();
const visible = ref<boolean>(false);
const detailsVisible = ref<boolean>(false);
const handleResizeColumn = (w, col) => {
  col.width = w;
};

const rules: Record<string, Rule[]> = {
  scenarioName: [{ required: true, message: 'Please enter scenarioName' }],
  appId: [{ required: true, message: 'please select an appId' }],
  tenantCode: [{ required: true, message: 'Please select an tenantCode' }],
  requestMethod: [{ required: true, message: 'Please choose the requestMethod' }],
  apiPath: [{ required: true, message: 'please enter apiPath' }],
  description: [{ required: true, message: 'please enter description' }],
  headerKey: [{ required: true, message: 'Please select an headerKey' }],
  alignmentMode: [{ required: true, message: 'Please select an alignmentMode' }],
};
const showDrawer = () => {
  title.value = '新增业务场景';
  visible.value = true;
};
// 详细信息
const detailsHeaderDataSource: Ref<SceneParamItem[]> = ref([]);
const onDetails = async (scenarioId: string) => {
  let viewScenePageParam = {
    scenarioId: scenarioId,
  };
  let res = await viewScene(viewScenePageParam);
  detailsDataSource.value = res;
  detailsVisible.value = true;
  res.headers.map((e) => {
    return detailsHeaderDataSource.value.push(e);
  });
};
// 新增
let headerDataSource: Ref<SceneParamItem[]> = ref([]);
const drawerRef = ref();
const formRef = ref();
const onSubmit = async () => {
  return formRef.value.validate();
};
const count = computed(() => headerDataSource.value.length + 1);
const handleAdd = () => {
  const header = {
    key: `${count.value}`,
    headerKey: '',
    headerMatch: '',
    headerValue: '',
  };
  headerDataSource.value.push(header);
};

const onDelete = (key: string) => {
  headerDataSource.value = headerDataSource.value.filter((item) => item.key !== key);
};
const onClose = () => {
  formRef.value.resetFields();
  headerDataSource.value = [];
  visible.value = false;
};
const detailsClose = () => {
  detailsDataSource.value = {
    id: '',
    scenarioName: '',
    appName: '',
    tenantName: '',
    requestMethod: '',
    apiPath: '',
    description: '',
    appId: '',
    tenantCode: '',
    headers: [],
  };
  detailsHeaderDataSource.value = [];
  detailsVisible.value = false;
};

// 编辑
const showEditDrawer = () => {
  title.value = '编辑业务场景';
  visible.value = true;
};
const onEdit = async (scenarioId: string) => {
  let viewScenePageParam = {
    scenarioId: scenarioId,
  };
  let res = await viewScene(viewScenePageParam);
  form.scenarioName = res.scenarioName;
  form.tenantCode = res.tenantCode;
  form.requestMethod = res.requestMethod;
  form.appId = res.appId;
  form.apiPath = res.apiPath;
  form.description = res.description;
  form.id = res.id;
  form.appName = res.appName;
  form.tenantName = res.tenantName;
  res.headers.map((sceneParamItem: SceneParamItem) => {
    return headerDataSource.value.push(sceneParamItem);
  });
  showEditDrawer();
};

// 分页查询
let current = ref(1);
let size = ref(10);
let total = ref(0);

async function getTenant() {
  let res = await getTenantList();
  tenantOptions.value = res;
}

async function getScene() {
  let changedParams = {
    current: current.value,
    size: size.value,
    appId: app.value,
    tenantCode: tenant.value,
  };

  try {
    let res = await getSceneList(changedParams);
    dataSource.value = res.items;
    total.value = res.total;
  } finally {
    loading.value = false;
  }
}

// 重置
async function handleReset() {
  app.value = '';
  tenant.value = '';
  await getScene();
}

async function getApp() {
  let res = await getAppList();
  appOptions.value = res;
}

const pagination = computed(() => ({
  showSizeChanger: false,
  current: current.value,
  size: size.value,
  total: total.value,
  pageSizeOptions: [5, 10, 20, 30, 40, 100],
  showTotal: (total: string) => {
    return `共 ${total} 条`;
  },
}));
const handleTableChange: TableProps['onChange'] = (pag) => {
  pagination.value.current = pag.current;
  pagination.value.size = pag.size;
  size.value = pag.size;
  current.value = pag.current;
  if (Number(size.value) > 10) {
    scroll.value = { y: 500 };
  }
  getScene();
};

const onSub = async () => {
  onSubmit()
    .then(() => {
      headerDataSource.value.forEach((e) => form.headers.push(e));
      if (title.value === '新增业务场景') {
        createScene(form)
          .then(() => {
            getScene();
          })
          .catch((e) => {
            message.error('新增业务场景失败' + e.response.data.msg);
          })
          .finally(() => {
            form.headers = [];
          });
      } else {
        editScene(form)
          .then(() => {
            getScene();
          })
          .catch((e) => {
            message.error('编辑业务场景失败' + e.response.data.msg);
          })
          .finally(() => {
            form.headers = [];
          });
      }
      visible.value = false;
    })
    .catch();
};

async function onDel(record: Recordable) {
  const res = await deleteScene({ scenarioId: record.id });
  if (res === '删除业务场景成功') {
    message.success('删除业务场景成功');
  } else {
    message.error('删除业务场景时遇到错误：' + res);
  }
  await getScene();
}

watch(
  () => form.appId,
  async (value) => {
    let res = await getTenantByAppId({ appId: value });
    tenantAddOptions.value = res;
    tenantSwatch.value = false;
  }
);
getTenant();
getApp();
getScene();
</script>

<style lang="less"></style>
